import { Request, Response, NextFunction } from 'express';
import { prisma } from '../../config/database';
import { logger } from '../../utils/logger';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { BUSINESS_ERROR_CODES, VALIDATION_ERROR_CODES } from '../../utils/errorCodes';

export class PermissionController extends BaseController {
  // 获取权限列表
  async getPermissions(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, search = '', module } = req.query;
      const pageNum = parseInt(page as string);
      const limitNum = parseInt(limit as string);
      const skip = (pageNum - 1) * limitNum;

      // 构建查询条件
      const where: any = {};
      
      if (search) {
        where.OR = [
          { name: { contains: search as string } },
          { code: { contains: search as string } },
          { description: { contains: search as string } }
        ];
      }

      if (module) {
        where.module = module;
      }

      // 查询权限列表
      const [permissions, total] = await Promise.all([
        prisma.permission.findMany({
          where,
          select: {
            id: true,
            name: true,
            code: true,
            description: true,
            module: true,
            createdAt: true,
            updatedAt: true,
            _count: {
              select: {
                rolePermissions: true
              }
            }
          },
          skip,
          take: limitNum,
          orderBy: { createdAt: 'desc' }
        }),
        prisma.permission.count({ where })
      ]);
      ResponseUtils.paginated(res, permissions, total, pageNum, limitNum);
    } catch (error) {
      next(error);
    }
  }

  // 获取权限详情
  async getPermissionById(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const permissionId = parseInt(id);

      if (isNaN(permissionId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的权限ID');
        return;
      }

      const permission = await prisma.permission.findUnique({
        where: { id: permissionId },
        select: {
          id: true,
          name: true,
          code: true,
          description: true,
          module: true,
          createdAt: true,
          updatedAt: true,
          rolePermissions: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true
                }
              }
            }
          }
        }
      });

      if (!permission) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_NOT_FOUND, '权限不存在');
        return;
      }

      ResponseUtils.success(res, { permission });
    } catch (error) {
      next(error);
    }
  }

  // 创建权限
  async createPermission(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { name, code, description, module } = req.body;

      // 验证必需字段
      if (!name || !code) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '权限名称和代码为必填项');
        return;
      }

      // 检查权限代码是否已存在
      const existingPermission = await prisma.permission.findUnique({
        where: { code }
      });

      if (existingPermission) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_ALREADY_EXISTS, '权限代码已存在');
        return;
      }

      // 创建权限
      const permission = await prisma.permission.create({
        data: {
          name,
          code,
          description,
          module
        },
        select: {
          id: true,
          name: true,
          code: true,
          description: true,
          module: true,
          createdAt: true
        }
      });

      logger.info(`权限创建成功: ${permission.name} (代码: ${permission.code})`);
      ResponseUtils.created(res, { permission });
    } catch (error) {
      next(error);
    }
  }

  // 更新权限
  async updatePermission(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { name, code, description, module } = req.body;
      const permissionId = parseInt(id);

      if (isNaN(permissionId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的权限ID');
        return;
      }

      // 检查权限是否存在
      const existingPermission = await prisma.permission.findUnique({
        where: { id: permissionId }
      });

      if (!existingPermission) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_NOT_FOUND, '权限不存在');
        return;
      }

      // 检查权限代码是否被其他权限使用
      if (code && code !== existingPermission.code) {
        const duplicatePermission = await prisma.permission.findUnique({
          where: { code }
        });

        if (duplicatePermission) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_ALREADY_EXISTS, '权限代码已存在');
          return;
        }
      }

      // 更新权限
      const updateData: any = {};
      if (name !== undefined) updateData.name = name;
      if (code !== undefined) updateData.code = code;
      if (description !== undefined) updateData.description = description;
      if (module !== undefined) updateData.module = module;

      const permission = await prisma.permission.update({
        where: { id: permissionId },
        data: updateData,
        select: {
          id: true,
          name: true,
          code: true,
          description: true,
          module: true,
          updatedAt: true
        }
      });

      logger.info(`权限更新成功: ${permission.name} (代码: ${permission.code})`);
      ResponseUtils.updated(res, { permission });
    } catch (error) {
      next(error);
    }
  }

  // 删除权限
  async deletePermission(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const permissionId = parseInt(id);

      if (isNaN(permissionId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的权限ID');
        return;
      }

      // 检查权限是否存在
      const existingPermission = await prisma.permission.findUnique({
        where: { id: permissionId }
      });

      if (!existingPermission) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_NOT_FOUND, '权限不存在');
        return;
      }

      // 检查是否有角色使用此权限
      const roleCount = await prisma.rolePermission.count({
        where: { permissionId }
      });

      if (roleCount > 0) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_IN_USE, '该权限正在被角色使用，无法删除');
        return;
      }

      // 删除权限
      await prisma.permission.delete({
        where: { id: permissionId }
      });

      logger.info(`权限删除成功: ${existingPermission.name} (代码: ${existingPermission.code})`);
      ResponseUtils.deleted(res);
    } catch (error) {
      next(error);
    }
  }

  // 获取权限统计信息
  async getPermissionStats(_req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      // 获取权限总数
      const totalPermissions = await prisma.permission.count();

      // 获取有角色的权限数
      const permissionsWithRoles = await prisma.permission.count({
        where: {
          rolePermissions: {
            some: {}
          }
        }
      });

      // 获取模块分布
      const moduleDistribution = await prisma.permission.groupBy({
        by: ['module'],
        _count: {
          id: true
        },
        orderBy: {
          _count: {
            id: 'desc'
          }
        }
      });

      // 获取最常用的权限
      const topPermissions = await prisma.permission.findMany({
        select: {
          id: true,
          name: true,
          code: true,
          module: true,
          _count: {
            select: {
              rolePermissions: true
            }
          }
        },
        orderBy: {
          rolePermissions: {
            _count: 'desc'
          }
        },
        take: 10
      });

      // 获取未使用的权限
      const unusedPermissions = await prisma.permission.findMany({
        where: {
          rolePermissions: {
            none: {}
          }
        },
        select: {
          id: true,
          name: true,
          code: true,
          module: true
        },
        take: 10
      });

      const stats = {
        total: totalPermissions,
        withRoles: permissionsWithRoles,
        withoutRoles: totalPermissions - permissionsWithRoles,
        moduleDistribution: moduleDistribution.map(item => ({
          module: item.module,
          count: item._count.id
        })),
        topPermissions: topPermissions.map(permission => ({
          id: permission.id,
          name: permission.name,
          code: permission.code,
          module: permission.module,
          roleCount: permission._count.rolePermissions
        })),
        unusedPermissions: unusedPermissions.map(permission => ({
          id: permission.id,
          name: permission.name,
          code: permission.code,
          module: permission.module
        }))
      };

      ResponseUtils.success(res, stats);
    } catch (error) {
      next(error);
    }
  }

  // 获取权限模块列表
  async getPermissionModules(_req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const modules = await prisma.permission.groupBy({
        by: ['module'],
        _count: {
          id: true
        },
        orderBy: {
          module: 'asc'
        }
      });

      const moduleList = modules.map(item => ({
        module: item.module,
        count: item._count.id
      }));

      ResponseUtils.success(res, { modules: moduleList });
    } catch (error) {
      next(error);
    }
  }

  // 批量创建权限
  async batchCreatePermissions(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { permissions } = req.body;

      if (!Array.isArray(permissions) || permissions.length === 0) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '权限列表不能为空');
        return;
      }

      const results = [];
      const errors = [];

      for (const permission of permissions) {
        try {
          const { name, code, description, module } = permission;

          if (!name || !code) {
            errors.push({ code, error: '权限名称和代码为必填项' });
            continue;
          }

          // 检查权限代码是否已存在
          const existingPermission = await prisma.permission.findUnique({
            where: { code }
          });

          if (existingPermission) {
            errors.push({ code, error: '权限代码已存在' });
            continue;
          }

          const createdPermission = await prisma.permission.create({
            data: {
              name,
              code,
              description,
              module
            }
          });

          results.push(createdPermission);
        } catch (error) {
          errors.push({ code: permission.code, error: '创建失败' });
        }
      }

      logger.info(`批量创建权限: ${results.length} 个成功, ${errors.length} 个失败`);
      ResponseUtils.success(res, { results, errors });
    } catch (error) {
      next(error);
    }
  }

  // 获取权限树结构
  async getPermissionTree(_req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const permissions = await prisma.permission.findMany({
        select: {
          id: true,
          name: true,
          code: true,
          description: true,
          module: true,
          _count: {
            select: {
              rolePermissions: true
            }
          }
        },
        orderBy: [
          { module: 'asc' },
          { name: 'asc' }
        ]
      });

      // 按模块分组构建树结构
      const tree = permissions.reduce((acc, permission) => {
        const module = permission.module || '其他';
        
        if (!acc[module]) {
          acc[module] = {
            module,
            permissions: []
          };
        }

        acc[module].permissions.push({
          id: permission.id,
          name: permission.name,
          code: permission.code,
          description: permission.description,
          roleCount: permission._count.rolePermissions
        });

        return acc;
      }, {} as Record<string, any>);

      const treeArray = Object.values(tree);

      ResponseUtils.success(res, { tree: treeArray });
    } catch (error) {
      next(error);
    }
  }
} 